#pragma once

#ifdef __cplusplus 
extern "C" {
#endif

#include <stdint.h>

#pragma pack(push, 8)
typedef struct {        /* unix time struct */
    int64_t time;      /* time (s) expressed by standard time_t */
    double   sec;       /* fraction of second under 1 s */
} unix_t;

typedef struct 
{
	double   sec;
	uint16_t year;
	uint8_t  month;
	uint8_t  day;
	uint8_t  hour;
	uint8_t  min;
}utc_t;

typedef struct 
{
	int32_t  week;
	double   itow;
}gpst_t;

#pragma pack(pop)

extern utc_t utc;
extern unix_t unix, unix1;
extern gpst_t gpst;

void utc2unix(const utc_t *ep, unix_t *t);
void unix2utc(const unix_t *t, utc_t *ep);
void gpst2unix(const gpst_t *gpst, unix_t *t, int leapSec);  // 考虑闰秒 +18
void unix2gpst(const unix_t *t, gpst_t *gpst, int leapSec);  // 考虑闰秒 +18

#pragma pack(push, 4)
struct tSync_s
{
	volatile uint64_t syst_ms;					// 在systick中断中调用，周期1ms
	double   syst_us;
	int64_t  unix_s;				   		    // 在1pps中断中调用，周期1s
	double   unix_us;
	double   cur_1pps_syst_us, last_1pps_syst_us;
	uint32_t trigger_1pps_cnt;
	uint32_t unix_err_cnt;
	
	void (*calc_syst_us)(struct tSync_s *t);
	void (*calc_unix_s) (struct tSync_s* t);
	void (*calib_unix_s)(struct tSync_s* t, int64_t unix_ref);

	uint64_t(*get_syst_ms)(struct tSync_s* t);
	double  (*get_syst_us)(struct tSync_s* t);
	double  (*get_unix_us)(struct tSync_s* t);
	double  (*get_tk_us)  (struct tSync_s* t);
};
#pragma pack(pop)
extern struct tSync_s t;

void tSync_calc_syst_us(struct tSync_s* t);
void tSync_calc_unix_s(struct tSync_s* t);
void tSync_calib_unix_s(struct tSync_s* t, int64_t unix_ref);

uint64_t tSync_get_syst_ms(struct tSync_s* t);
double   tSync_get_unix_us (struct tSync_s* t);
double   tSync_get_syst_us(struct tSync_s* t);
double   tSync_get_tk_us(struct tSync_s* t);

#ifdef __cplusplus
}
#endif
